package ytdp.careagle.com.ytdp.myview;

import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.Toast;


import org.greenrobot.eventbus.EventBus;

import java.io.IOException;
import java.util.List;

import ytdp.careagle.com.ytdp.R;
import ytdp.careagle.com.ytdp.app.G;
import ytdp.careagle.com.ytdp.utils.MyBitmapUtils;
import ytdp.careagle.com.ytdp.utils.MyToast;
import ytdp.careagle.com.ytdp.utils.RxPromisUtils;


/**
 * Created by lida
 */
public class CameraSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Camera.AutoFocusCallback {

    private static final String TAG = "CameraSurfaceView";
    private static final int MSG_DO_AUTO_FOCUS = 1;
    private static float scale = 4 / 3;

    private Context mContext;
    private SurfaceHolder holder;
    private Camera mCamera;

    private int mScreenWidth;
    private int mScreenHeight;
    private boolean isVertical;


    public CameraSurfaceView(Context context) {
        this(context, null);
    }

    public CameraSurfaceView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CameraSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mContext = context;
        getScreenMetrix(context);
        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.CameraSurfaceView);
        String picScale = a.getString(R.styleable.CameraSurfaceView_picScale);
        isVertical = a.getBoolean(R.styleable.CameraSurfaceView_isVertical, true);
        if (!TextUtils.isEmpty(picScale) && picScale.equals("16_9")) {
            scale = (float) 16 / 9;
        } else {
            scale = (float) 4 / 3;
        }
        a.recycle();
        initView();
    }

    private void getScreenMetrix(Context context) {
        WindowManager WM = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        WM.getDefaultDisplay().getMetrics(outMetrics);
        mScreenWidth = outMetrics.widthPixels;
        mScreenHeight = outMetrics.heightPixels;
    }

    private void initView() {
        holder = getHolder();//获得surfaceHolder引用
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//设置类型
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        Log.i(TAG, "surfaceCreated");
        if (mCamera == null) {
            try {
                mCamera = Camera.open(G.CAMERA_FRONT_OR_BACK);//开启相机
                mCamera.setPreviewDisplay(holder);//摄像头画面显示在Surface上
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Log.i(TAG, "surfaceChanged");
        try {
            //设置参数并开始预览
            if (mCamera != null) {
                setCameraParams(mCamera, mScreenWidth, mScreenHeight);
                mCamera.startPreview();
                isPreview = true;
                //        mCamera.cancelAutoFocus();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        Log.i(TAG, "surfaceDestroyed");
        try {
            if (mCamera != null) {
                mCamera.stopPreview();//停止预览
                isPreview = false;
                mCamera.release();//释放相机资源
                mCamera = null;
                holder = null;
            }
        } catch (Exception e) {
        }

    }

    @Override
    public void onAutoFocus(boolean success, Camera Camera) {
        if (success) {
            Log.i(TAG, "onAutoFocus success=" + success);
        }
    }

    // 拍照瞬间调用
    private Camera.ShutterCallback shutter = new Camera.ShutterCallback() {
        @Override
        public void onShutter() {
            Log.i(TAG, "shutter");
        }
    };

    // 获得没有压缩过的图片数据
    private Camera.PictureCallback raw = new Camera.PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera Camera) {
            Log.i(TAG, "raw");

        }
    };

    //创建jpeg图片回调数据对象
    private Camera.PictureCallback jpeg = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(final byte[] data, Camera Camera) {
            try {
                Bitmap bm = MyBitmapUtils.zoomImg(data, scale);
                EventBus.getDefault().post(bm);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (mCamera != null) {
                        mCamera.stopPreview();// 关闭预览
                        isPreview = false;
//                        mCamera.startPreview();
//                        mCamera.cancelAutoFocus();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
    };

    public Camera getCamera() {
        return mCamera;
    }

    public void setAutoFocus() {
        if (mCamera != null) {
            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
            mCamera.setParameters(parameters);
            mCameraAutoFocusHandler.sendEmptyMessageDelayed(MSG_DO_AUTO_FOCUS, 200);
//            mCamera.autoFocus(this);
        }
    }

    private final Handler mCameraAutoFocusHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_DO_AUTO_FOCUS:
                    if (mCamera != null) {
                        try {
                            mCamera.autoFocus(CameraSurfaceView.this);
                        } catch (Exception e) {
                        }
                    }
                    break;
            }
        }
    };

    public void takePicture() {
        if (mCamera != null) {
            //设置参数,并拍照
            setCameraParams(mCamera, mScreenWidth, mScreenHeight);
            // 当调用camera.takePiture方法后，camera关闭了预览，这时需要调用startPreview()来重新开启预览
            try {
                mCamera.takePicture(null, null, jpeg);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private boolean isSetParmars = false;

    private void setCameraParams(Camera camera, int width, int height) {
        if (mCamera == null) {
            return;
        }
        Camera.Parameters parameters = mCamera.getParameters();
        // 获取摄像头支持的PictureSize列表
        List<Camera.Size> pictureSizeList = parameters.getSupportedPictureSizes();
        /**从列表中选取合适的分辨率*/
        Camera.Size picSize = null;
        Camera.Size picSizeMax = null;
        if (pictureSizeList != null && pictureSizeList.size() != 0) {
            for (Camera.Size size : pictureSizeList) {
                if (size == null) {
                    continue;
                }
                float i = (float) size.width / size.height;
                float i1 = (float) scale;
                if (i == i1 && size.width > 1000) {
                    picSize = size;
                    break;
                }
                if (picSizeMax == null || size.width >= picSizeMax.width) {
                    picSizeMax = size;
                }
            }
        }
        if (picSize == null) {
            picSize = picSizeMax;
        }

//         获取摄像头支持的PreviewSize列表
        List<Camera.Size> previewSizeList = parameters.getSupportedPreviewSizes();
        Camera.Size preSize = null;
        Camera.Size preSizeMax = null;
        if (previewSizeList != null && previewSizeList.size() != 0) {
            int w = 0;
            for (Camera.Size size : previewSizeList) {
                if (size == null) {
                    continue;
                }
                float i = (float) size.width / size.height;
                float i1 = (float) scale;
                if (i == i1 && size.width > 1000) {
                    preSize = size;
                    break;
                }
                if (preSizeMax == null || size.width > preSizeMax.width) {
                    preSizeMax = size;
                }
            }
        }
        if (preSize == null) {
            preSize = preSizeMax;
        }
        if (picSize != null) {
            picSizeWidth = picSize.width;
            picSizeHeight = picSize.height;
        }
        if (preSize != null) {
            preSizeWidth = preSize.width;
            preSizeHeight = preSize.height;
        } else {
            preSizeWidth = 1280;
            preSizeHeight = 720;
        }
        parameters.setPreviewSize(preSizeWidth, preSizeHeight);//设置摄像头的预览尺寸
        parameters.setPictureSize(picSizeWidth, picSizeHeight);//设置摄像头的拍照图片尺寸
        parameters.setJpegQuality(70); // 设置照片质量
        if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) {
            parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);// 连续对焦模式
        }
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);// 连续对焦模式
        mCamera.cancelAutoFocus();//自动对焦。
        if (isVertical) {
            mCamera.setDisplayOrientation(90);// 设置PreviewDisplay的方向，效果就是将捕获的画面旋转多少度显示
        } else {
            mCamera.setDisplayOrientation(0);// 设置PreviewDisplay的方向，效果就是将捕获的画面旋转多少度显示
        }
        try {
            mCamera.setParameters(parameters);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private int preSizeWidth;
    private int picSizeWidth;
    private int preSizeHeight;
    private int picSizeHeight;

    /**
     * 从列表中选取合适的分辨率
     * 默认w:h = 4:3
     * <p>注意：这里的w对应屏幕的height
     * h对应屏幕的width<p/>
     */
    private Camera.Size getProperSize(List<Camera.Size> pictureSizeList, float screenRatio) {
        Log.i(TAG, "screenRatio=" + screenRatio);
        Camera.Size result = null;
        for (Camera.Size size : pictureSizeList) {
            float currentRatio = ((float) size.width) / size.height;
            if (currentRatio - screenRatio == 0) {
                result = size;
                break;
            }
        }

        if (null == result) {
            for (Camera.Size size : pictureSizeList) {
                float curRatio = ((float) size.width) / size.height;
                if (curRatio == 4f / 3) {// 默认w:h = 4:3
                    result = size;
                    break;
                }
            }
        }

        return result;
    }


    public void setCamera(Camera camera) {
        mCamera = camera;
        if (mCamera != null) {
            try {
                mCamera.setPreviewDisplay(getHolder());
                mCamera.startPreview();
                setCameraParams(null, 0, 0);
            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }

    //闪光灯
    public boolean startLight(Context context) {
        boolean result = false;
        if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
            String mess = getResources().getString(R.string.toast_flash);
            Toast.makeText(context, mess, Toast.LENGTH_LONG).show();
        } else {
            if (mCamera != null) {
                Camera.Parameters parameters = mCamera.getParameters();
                String flashMode = parameters.getFlashMode();
                if (flashMode.equals(Camera.Parameters.FLASH_MODE_TORCH)) {
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                    parameters.setExposureCompensation(0);
                    result = true;
                } else {
                    parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
                    parameters.setExposureCompensation(-1);
                    result = false;
                }
                try {
                    mCamera.setParameters(parameters);
                } catch (Exception e) {
                    String mess = getResources().getString(R.string.toast_flash);
                    Toast.makeText(context, mess, Toast.LENGTH_LONG).show();
                    result = false;
                }
                mCamera.startPreview();
            }
        }
        return result;
    }

    public void stopCameraPreview() {
        if (mCamera != null) {
            try {
//                mCamera.cancelAutoFocus();
                mCamera.setOneShotPreviewCallback(null);
                mCamera.stopPreview();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        isPreview = false;
    }

    public boolean isPreview() {
        return isPreview;
    }

    private boolean isPreview = true;

    public void startCameraPreview() {
        if (mCamera != null) {
            try {
                mCamera.setPreviewDisplay(getHolder());
                mCamera.startPreview();
                setCameraParams(null, 0, 0);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        isPreview = true;
    }

    public void cwStopCamera() {
        if (mCamera != null) {
            stopCameraPreview();
            mCamera.release();
            mCamera = null;
        }
        isPreview = false;
    }

    /**
     * 打开摄像头开始预览，但是并未开始识别
     */
    public void cwStartCamera() {
        isPreview = true;
        if (mCamera != null) {
            return;
        }
        try {
            mCamera = Camera.open(G.CAMERA_FRONT_OR_BACK);
        } catch (Exception e) {
            Log.e("tag", e.getMessage());
        }
        setCamera(mCamera);

    }

    public void release() {
        if (mCamera != null) {
            mCamera.release();
        }
    }
}
